package com.talkweb.reader.component;

import com.talkweb.baselibrary.annotation.Nullable;
import com.talkweb.reader.ResourceTable;
import ohos.agp.colors.RgbColor;
import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.components.ScrollHelper;
import ohos.agp.components.element.PixelMapElement;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.render.*;
import ohos.agp.utils.Color;
import ohos.agp.utils.Matrix;
import ohos.agp.utils.Point;
import ohos.agp.utils.TextAlignment;
import ohos.app.Context;
import ohos.media.codec.TrackInfo;
import ohos.media.image.PixelMap;
import ohos.media.image.common.Size;
import ohos.multimodalinput.event.MmiPoint;
import ohos.multimodalinput.event.TouchEvent;

public class BookPageComponent extends Component implements Component.EstimateSizeListener,
        Component.DrawTask,Component.TouchEventListener {
    private Paint pointPaint;//绘制各标识点的画笔
    private Paint bgPaint;//背景画笔
    private Paint pathAPaint;//绘制A区域画笔
    private Paint pathBPaint;//绘制B区域画笔
    private Paint pathCPaint;//绘制C区域画笔
    private Paint textPaint;//绘制文字画笔
    private Paint pathCContentPaint;//绘制C区域内容画笔

    private MyPoint a,f,g,e,h,c,j,b,k,d,i;
    private Path pathA;
    private Path pathB;
    private Path pathC;

    private int viewWidth;
    private int viewHeight;

    float lPathAShadowDis = 0;//A区域左阴影矩形短边长度参考值
    float rPathAShadowDis = 0;//A区域右阴影矩形短边长度参考值
    private float[] mMatrixArray = { 0, 0, 0, 0, 0, 0, 0, 0, 1.0f };
    private Matrix mMatrix;

    private ScrollHelper mScroller;

    private String style;
    public static final String STYLE_LEFT = "STYLE_LEFT";//点击左边区域
    public static final String STYLE_RIGHT = "STYLE_RIGHT";//点击右边区域
    public static final String STYLE_MIDDLE = "STYLE_MIDDLE";//点击中间区域
    public static final String STYLE_TOP_RIGHT = "STYLE_TOP_RIGHT";//f点在右上角
    public static final String STYLE_LOWER_RIGHT = "STYLE_LOWER_RIGHT";//f点在右下角

    private ShapeElement drawableLeftTopRight;
    private ShapeElement drawableLeftLowerRight;

    private ShapeElement drawableRightTopRight;
    private ShapeElement drawableRightLowerRight;
    private ShapeElement drawableHorizontalLowerRight;

    private ShapeElement drawableBTopRight;
    private ShapeElement drawableBLowerRight;

    private ShapeElement drawableCTopRight;
    private ShapeElement drawableCLowerRight;

    private PixelMap pathAContentBitmap;//A区域内容Bitmap
    private PixelMap pathBContentBitmap;//B区域内容Bitmap
    private PixelMap pathCContentBitmap;//C区域内容Bitmap

    private String bookConStr1 = "开车去梁端学校的路上，谢晓晖接到老同学沈军的电话，一接起来就听到他略显不满的声音。";
    private String bookConStr2 = "晓晖，我这两天给你发的微信你怎么一条都不回啊？行不行也给个话呗。”\n";
    private String bookConStr3 = "什么微信？”谢晓晖瞥了一眼放在一边的手机，解释道：“我这两天太忙，根本没时间看手机，什么事你现在说吧。";
    private String bookConStr4 = "沈军无奈地叹气道：“就是上次吃饭的时候我跟你提过的，我有个挺好的朋友托我问问能不能安排他儿子到你的工作室去做助理。那朋友说他儿子本来就是学艺术的，之前一直在国外留学工作……";

    public BookPageComponent(Context context) {
        super(context);
        init(context,null);
    }

    public BookPageComponent(Context context, @Nullable AttrSet attrs) {
        super(context, attrs);
        init(context,attrs);
    }

    private void init(Context context, @Nullable AttrSet attrs){

        a = new MyPoint();
        f = new MyPoint();
        g = new MyPoint();
        e = new MyPoint();
        h = new MyPoint();
        c = new MyPoint();
        j = new MyPoint();
        b = new MyPoint();
        k = new MyPoint();
        d = new MyPoint();
        i = new MyPoint();

        pointPaint = new Paint();
        pointPaint.setColor(Color.RED);
        pointPaint.setTextSize(25);
        pointPaint.setStyle(Paint.Style.STROKE_STYLE);

        bgPaint = new Paint();
        bgPaint.setColor(Color.GREEN);

        pathAPaint = new Paint();
        pathAPaint.setColor(Color.GREEN);
        pathAPaint.setAntiAlias(true);//设置抗锯齿

        pathBPaint = new Paint();
        pathBPaint.setColor(new Color(mContext.getColor(ResourceTable.Color_colorBlue)));
        pathBPaint.setAntiAlias(true);//设置抗锯齿
//        pathBPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_ATOP));我们不需要单独绘制path了，记得注释掉

        pathCPaint = new Paint();
        pathCPaint.setColor(Color.YELLOW);
        pathCPaint.setAntiAlias(true);//设置抗锯齿
//        pathCPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_ATOP));
//        pathCPaint.setStyle(Paint.Style.STROKE);

        pathCContentPaint = new Paint();
        pathCContentPaint.setColor(Color.YELLOW);
        pathCContentPaint.setAntiAlias(true);//设置抗锯齿

        textPaint = new Paint();
        textPaint.setColor(Color.BLACK);
        textPaint.setTextAlign(TextAlignment.CENTER);
        textPaint.setSubpixelAntiAlias(true);//设置自像素。如果该项为true，将有助于文本在LCD屏幕上的显示效果。
        textPaint.setTextSize(30);

        pathA = new Path();
        pathB = new Path();
        pathC = new Path();

        style = STYLE_LOWER_RIGHT;
        mScroller = new ScrollHelper();
        mMatrix = new Matrix();

//        createGradientDrawable();
        setTouchEventListener(this::onTouchEvent);

        setEstimateSizeListener(this);
        addDrawTask(this::onDraw);

    }

    private void drawPathAContentBitmap(PixelMap bitmap,Paint pathPaint){
        Texture texture = new Texture(bitmap);
        Canvas mCanvas = new Canvas(texture);
        //下面开始绘制区域内的内容...
        mCanvas.drawPath(getPathDefault(),pathPaint);
        mCanvas.drawText(textPaint,bookConStr1, 20, 100);
        mCanvas.drawText(textPaint,bookConStr2, 40, 200);
        mCanvas.drawText(textPaint,bookConStr3, 40, 300);
        mCanvas.drawText(textPaint,bookConStr4, 40, 400);
    }

    private void drawPathBContentBitmap(PixelMap bitmap,Paint pathPaint){
        Texture texture = new Texture(bitmap);
        Canvas mCanvas = new Canvas(texture);
        //下面开始绘制区域内的内容...
        mCanvas.drawPath(getPathDefault(),pathPaint);
        mCanvas.drawText(textPaint,bookConStr1, 40, 100);
        mCanvas.drawText(textPaint,bookConStr2, 40, 200);
        mCanvas.drawText(textPaint,bookConStr3, 40, 300);
        mCanvas.drawText(textPaint,bookConStr4, 40, 400);
        //结束绘制区域内的内容...
    }

    @Override
    public boolean onEstimateSize(int widthEstimateConfig, int heightEstimateConfig) {
//        int height = measureSize(defaultHeight, widthEstimateConfig);
//        int width = measureSize(defaultWidth, heightEstimateConfig);
        int width = Component.EstimateSpec.getSize(widthEstimateConfig);
        int height = Component.EstimateSpec.getSize(heightEstimateConfig);
        setEstimatedSize(
                Component.EstimateSpec.getChildSizeWithMode(width, width, Component.EstimateSpec.PRECISE),
                Component.EstimateSpec.getChildSizeWithMode(height, height, Component.EstimateSpec.PRECISE)
        );

        viewWidth = width;
        viewHeight = height;
        a.x = -1;
        a.y = -1;
        PixelMap.InitializationOptions initializationOptions = new PixelMap.InitializationOptions();
        initializationOptions.size = new Size(viewWidth,viewHeight);
        pathAContentBitmap = PixelMap.create(initializationOptions);
        drawPathAContentBitmap(pathAContentBitmap,pathAPaint);

        pathBContentBitmap = PixelMap.create(initializationOptions);
        drawPathBContentBitmap(pathBContentBitmap,pathBPaint);

        pathCContentBitmap = PixelMap.create(initializationOptions);
        drawPathAContentBitmap(pathCContentBitmap,pathCPaint);
        return false;
    }



    private int measureSize(int defaultSize,int measureSpec) {
        int result = defaultSize;
        int specMode = Component.EstimateSpec.getMode(measureSpec);
        int specSize = Component.EstimateSpec.getSize(measureSpec);

        if (specMode == EstimateSpec.PRECISE) {
            result = specSize;
        } else if (specMode == EstimateSpec.NOT_EXCEED) {
            result = Math.min(result, specSize);
        }
        return result;
    }

    @Override
    public void onDraw(Component component, Canvas canvas) {
        canvas.drawColor(Color.YELLOW.getValue(),BlendMode.DARKEN);
        if(a.x==-1 && a.y==-1){
            drawPathAContent(canvas,getPathDefault());
        }else {
            if(f.x==viewWidth && f.y==0){
                drawPathAContent(canvas,getPathAFromTopRight());

                drawPathCContent(canvas,getPathAFromTopRight());
                drawPathBContent(canvas,getPathAFromTopRight());
            }else if(f.x==viewWidth && f.y==viewHeight){

//                beginTrace("drawPathA");
                drawPathAContent(canvas,getPathAFromLowerRight());
//                endTrace();

//                beginTrace("drawPathC");
                drawPathCContent(canvas,getPathAFromLowerRight());
//                endTrace();

//                beginTrace("drawPathB");
                drawPathBContent(canvas,getPathAFromLowerRight());
//                endTrace();
            }
        }
    }




//    private void beginTrace(String tag){
//        Trace.beginSection(tag);
//    }
//
//    private void endTrace(){
//        Trace.endSection();
//    }

//    @Override
//    public void computeScroll() {
//        if (mScroller.computeScrollOffset()) {
//            float x = mScroller.getCurrX();
//            float y = mScroller.getCurrY();
//            if(style.equals(STYLE_TOP_RIGHT)){
//                setTouchPoint(x,y,STYLE_TOP_RIGHT);
//            }else {
//                setTouchPoint(x,y,STYLE_LOWER_RIGHT);
//            }
//            if (mScroller.getFinalX() == x && mScroller.getFinalY() == y){
//                setDefaultPath();
//            }
//        }
//    }



    @Override
    public boolean onTouchEvent(Component component, TouchEvent touchEvent) {
        MmiPoint absPoint = touchEvent.getPointerPosition(touchEvent.getIndex());
        Point point = new Point(absPoint.getX() - getContentPositionX(),
                absPoint.getY() - getContentPositionY());
        float x = point.getPointX();
        float y = point.getPointY();
        switch (touchEvent.getAction()){
            case TouchEvent.PRIMARY_POINT_DOWN:
                if(x<=viewWidth/3){//左
                    style = STYLE_LEFT;
                    setTouchPoint(x,y,style);

                }else if(x>viewWidth/3 && y<=viewHeight/3){//上
                    style = STYLE_TOP_RIGHT;
                    setTouchPoint(x,y,style);

                }else if(x>viewWidth*2/3 && y>viewHeight/3 && y<=viewHeight*2/3){//右
                    style = STYLE_RIGHT;
                    setTouchPoint(x,y,style);

                }else if(x>viewWidth/3 && y>viewHeight*2/3){//下
                    style = STYLE_LOWER_RIGHT;
                    setTouchPoint(x,y,style);

                }else if(x>viewWidth/3 && x<viewWidth*2/3 && y>viewHeight/3 && y<viewHeight*2/3){//中
                    style = STYLE_MIDDLE;
                }
                break;
            case TouchEvent.POINT_MOVE:
                setTouchPoint(x,y,style);
                break;
            case TouchEvent.PRIMARY_POINT_UP:
                startCancelAnim();
                break;
        }
        return true;
    }

    /**
     * 取消翻页动画,计算滑动位置与时间
     */
    public void startCancelAnim(){
        int dx,dy;
        //让a滑动到f点所在位置，留出1像素是为了防止当a和f重叠时出现View闪烁的情况
        if(style.equals(STYLE_TOP_RIGHT)){
            dx = (int) (viewWidth-1-a.x);
            dy = (int) (1-a.y);
        }else {
            dx = (int) (viewWidth-1-a.x);
            dy = (int) (viewHeight-1-a.y);
        }
        mScroller.startScroll((int) a.x, (int) a.y, dx, dy);
    }

    /**
     * 设置触摸点
     * @param x
     * @param y
     * @param style
     */
    public void setTouchPoint(float x, float y, String style){
        MyPoint touchPoint = new MyPoint();
        a.x = x;
        a.y = y;
        this.style = style;
        switch (style){
            case STYLE_TOP_RIGHT:
                f.x = viewWidth;
                f.y = 0;
                calcPointsXY(a,f);
                touchPoint = new MyPoint(x,y);
                if(calcPointCX(touchPoint,f)<0){//如果c点x坐标小于0则重新测量a点坐标
                    calcPointAByTouchPoint();
                    calcPointsXY(a,f);
                }
                invalidate();
                break;
            case STYLE_LEFT:
            case STYLE_RIGHT:
                a.y = viewHeight-1;
                f.x = viewWidth;
                f.y = viewHeight;
                calcPointsXY(a,f);
                invalidate();
                break;
            case STYLE_LOWER_RIGHT:
                f.x = viewWidth;
                f.y = viewHeight;
                calcPointsXY(a,f);
                touchPoint = new MyPoint(x,y);
                if(calcPointCX(touchPoint,f)<0){//如果c点x坐标小于0则重新测量a点坐标
                    calcPointAByTouchPoint();
                    calcPointsXY(a,f);
                }
                invalidate();
                break;
            default:
                break;
        }
    }

    /**
     * 如果c点x坐标小于0,根据触摸点重新测量a点坐标
     */
    private void calcPointAByTouchPoint(){
        float w0 = viewWidth - c.x;

        float w1 = Math.abs(f.x - a.x);
        float w2 = viewWidth * w1 / w0;
        a.x = Math.abs(f.x - w2);

        float h1 = Math.abs(f.y - a.y);
        float h2 = w2 * h1 / w1;
        a.y = Math.abs(f.y - h2);
    }

    /**
     * 回到默认状态
     */
    public void setDefaultPath(){
        a.x = -1;
        a.y = -1;
        invalidate();
    }

    /**
     * 初始化各区域阴影GradientDrawable
     */
    private void createGradientDrawable(){
        int deepColor = 0x33333333;
        int lightColor = 0x01333333;
        int[] gradientColors = new int[]{lightColor,deepColor};//渐变颜色数组
        drawableLeftTopRight = new ShapeElement();
        drawableLeftTopRight.setGradientOrientation(ShapeElement.Orientation.LEFT_TO_RIGHT);
        RgbColor[] rgbColors1 = new RgbColor[]{RgbColor.fromArgbInt(deepColor),RgbColor.fromArgbInt(lightColor)};
        drawableLeftTopRight.setRgbColors(rgbColors1);
        drawableLeftTopRight.setShaderType(ShapeElement.LINEAR_GRADIENT_SHADER_TYPE);

        drawableLeftLowerRight = new ShapeElement();
        drawableLeftLowerRight.setGradientOrientation(ShapeElement.Orientation.RIGHT_TO_LEFT);
        RgbColor[] rgbColors2 = new RgbColor[]{RgbColor.fromArgbInt(deepColor),RgbColor.fromArgbInt(lightColor)};
        drawableLeftLowerRight.setRgbColors(rgbColors2);
        drawableLeftLowerRight.setShaderType(ShapeElement.LINEAR_GRADIENT_SHADER_TYPE);



        deepColor = 0x22333333;
        lightColor = 0x01333333;
        gradientColors =  new int[]{deepColor,lightColor,lightColor};
        drawableRightTopRight = new ShapeElement();
        drawableRightTopRight.setGradientOrientation(ShapeElement.Orientation.BOTTOM_TO_TOP);
        RgbColor[] rgbColors3 = new RgbColor[]{RgbColor.fromArgbInt(deepColor),
                RgbColor.fromArgbInt(lightColor), RgbColor.fromArgbInt(lightColor)};
        drawableRightTopRight.setRgbColors(rgbColors3);
        drawableRightTopRight.setShaderType(ShapeElement.LINEAR_GRADIENT_SHADER_TYPE);


        drawableRightLowerRight = new ShapeElement();
        drawableRightLowerRight.setGradientOrientation(ShapeElement.Orientation.TOP_TO_BOTTOM);
        RgbColor[] rgbColors4 = new RgbColor[]{RgbColor.fromArgbInt(deepColor),
                RgbColor.fromArgbInt(lightColor), RgbColor.fromArgbInt(lightColor)};
        drawableRightLowerRight.setRgbColors(rgbColors4);
        drawableRightLowerRight.setShaderType(ShapeElement.LINEAR_GRADIENT_SHADER_TYPE);

        deepColor = 0x44333333;
        lightColor = 0x01333333;
        gradientColors = new int[]{lightColor,deepColor};//渐变颜色数组
        drawableHorizontalLowerRight = new ShapeElement();
        drawableHorizontalLowerRight.setGradientOrientation(ShapeElement.Orientation.LEFT_TO_RIGHT);
        RgbColor[] rgbColors5 = new RgbColor[]{RgbColor.fromArgbInt(lightColor),
                RgbColor.fromArgbInt(deepColor)};
        drawableHorizontalLowerRight.setRgbColors(rgbColors5);
        drawableHorizontalLowerRight.setShaderType(ShapeElement.LINEAR_GRADIENT_SHADER_TYPE);

        deepColor = 0x55111111;
        lightColor = 0x00111111;
        gradientColors = new int[] {deepColor,lightColor};//渐变颜色数组

        drawableBTopRight = new ShapeElement();
        drawableBTopRight.setGradientOrientation(ShapeElement.Orientation.LEFT_TO_RIGHT);
        RgbColor[] rgbColors6 = new RgbColor[]{RgbColor.fromArgbInt(deepColor),
                RgbColor.fromArgbInt(lightColor)};
        drawableBTopRight.setRgbColors(rgbColors6);
        drawableBTopRight.setShaderType(ShapeElement.LINEAR_GRADIENT_SHADER_TYPE);


        drawableBLowerRight = new ShapeElement();
        drawableBLowerRight.setGradientOrientation(ShapeElement.Orientation.RIGHT_TO_LEFT);
        RgbColor[] rgbColors7 = new RgbColor[]{RgbColor.fromArgbInt(deepColor),
                RgbColor.fromArgbInt(lightColor)};
        drawableBLowerRight.setRgbColors(rgbColors7);
        drawableBLowerRight.setShaderType(ShapeElement.LINEAR_GRADIENT_SHADER_TYPE);

        deepColor = 0x55333333;
        lightColor = 0x00333333;
        gradientColors = new int[]{lightColor,deepColor};//渐变颜色数组

        drawableCTopRight = new ShapeElement();
        drawableCTopRight.setGradientOrientation(ShapeElement.Orientation.LEFT_TO_RIGHT);
        RgbColor[] rgbColors8 = new RgbColor[]{RgbColor.fromArgbInt(lightColor),
                RgbColor.fromArgbInt(deepColor)};
        drawableCTopRight.setRgbColors(rgbColors8);
        drawableCTopRight.setShaderType(ShapeElement.LINEAR_GRADIENT_SHADER_TYPE);

        drawableCLowerRight = new ShapeElement();
        drawableCLowerRight.setGradientOrientation(ShapeElement.Orientation.RIGHT_TO_LEFT);
        RgbColor[] rgbColors9 = new RgbColor[]{RgbColor.fromArgbInt(lightColor),
                RgbColor.fromArgbInt(deepColor)};
        drawableCLowerRight.setRgbColors(rgbColors9);
        drawableCLowerRight.setShaderType(ShapeElement.LINEAR_GRADIENT_SHADER_TYPE);
    }

    /**
     * 绘制A区域内容
     * @param canvas
     * @param pathA
     */
    private void drawPathAContent(Canvas canvas, Path pathA){
        canvas.save();
        canvas.clipPath(pathA, Canvas.ClipOp.INTERSECT);//对绘制内容进行裁剪，取和A区域的交集
        PixelMapHolder pixelMapHolder = new PixelMapHolder(pathAContentBitmap);
        canvas.drawPixelMapHolder(pixelMapHolder, 0, 0, pathCContentPaint);

//        if(style.equals(STYLE_LEFT) || style.equals(STYLE_RIGHT)){
//            drawPathAHorizontalShadow(canvas,pathA);
//        }else {
//            drawPathALeftShadow(canvas,pathA);
//            drawPathARightShadow(canvas,pathA);
//        }
        canvas.restore();
    }

    /**
     * 绘制A区域左阴影
     * @param canvas
     */
    private void drawPathALeftShadow(Canvas canvas, Path pathA){
        canvas.restore();
        canvas.save();

        int left;
        int right;
        int top = (int) e.y;
        int bottom = (int) (e.y+viewHeight);

        ShapeElement gradientDrawable;
        if (style.equals(STYLE_TOP_RIGHT)) {
            gradientDrawable = new ShapeElement();
            left = (int) (e.x - lPathAShadowDis /2);
            right = (int) (e.x);
        } else {
            gradientDrawable = drawableLeftLowerRight;
            left = (int) (e.x);
            right = (int) (e.x + lPathAShadowDis /2);
        }

        Path mPath = new Path();
        mPath.moveTo(a.x- Math.max(rPathAShadowDis, lPathAShadowDis) /2,a.y);
        mPath.lineTo(d.x,d.y);
        mPath.lineTo(e.x,e.y);
        mPath.lineTo(a.x,a.y);
        mPath.close();
        canvas.clipPath(pathA, Canvas.ClipOp.INTERSECT);
        canvas.clipPath(mPath, Canvas.ClipOp.INTERSECT);

        float mDegrees = (float) Math.toDegrees(Math.atan2(e.x-a.x, a.y-e.y));
        canvas.rotate(mDegrees, e.x, e.y);

        gradientDrawable.setBounds(left,top,right,bottom);
        gradientDrawable.drawToCanvas(canvas);
    }

    /**
     * 绘制A区域右阴影
     * @param canvas
     */
    private void drawPathARightShadow(Canvas canvas, Path pathA){
        canvas.restore();
        canvas.save();

        float viewDiagonalLength = (float) Math.hypot(viewWidth, viewHeight);//view对角线长度
        int left = (int) h.x;
        int right = (int) (h.x + viewDiagonalLength*10);//需要足够长的长度
        int top;
        int bottom;

        ShapeElement gradientDrawable;
        if (style.equals(STYLE_TOP_RIGHT)) {
            gradientDrawable = new ShapeElement();
            top = (int) (h.y- rPathAShadowDis /2);
            bottom = (int) h.y;
        } else {
            gradientDrawable = drawableRightLowerRight;
            top = (int) h.y;
            bottom = (int) (h.y+ rPathAShadowDis /2);
        }
        gradientDrawable.setBounds(left,top,right,bottom);

        Path mPath = new Path();
        mPath.moveTo(a.x- Math.max(rPathAShadowDis, lPathAShadowDis) /2,a.y);
//        mPath.lineTo(i.x,i.y);
        mPath.lineTo(h.x,h.y);
        mPath.lineTo(a.x,a.y);
        mPath.close();
        canvas.clipPath(pathA,Canvas.ClipOp.INTERSECT);
        canvas.clipPath(mPath, Canvas.ClipOp.INTERSECT);

        float mDegrees = (float) Math.toDegrees(Math.atan2(a.y-h.y, a.x-h.x));
        canvas.rotate(mDegrees, h.x, h.y);
        gradientDrawable.drawToCanvas(canvas);
    }

    /**
     * 绘制A区域水平翻页阴影
     * @param canvas
     */
    private void drawPathAHorizontalShadow(Canvas canvas, Path pathA){
        canvas.restore();
        canvas.save();
        canvas.clipPath(pathA, Canvas.ClipOp.INTERSECT);

        int maxShadowWidth = 30;//阴影矩形最大的宽度
        int left = (int) (a.x - Math.min(maxShadowWidth,(rPathAShadowDis/2)));
        int right = (int) (a.x);
        int top = 0;
        int bottom = viewHeight;
        ShapeElement gradientDrawable = drawableHorizontalLowerRight;
        gradientDrawable.setBounds(left,top,right,bottom);

        float mDegrees = (float) Math.toDegrees(Math.atan2(f.x-a.x,f.y-h.y));
        canvas.rotate(mDegrees, a.x, a.y);
        gradientDrawable.drawToCanvas(canvas);
    }

    /**
     * 绘制默认的界面
     * @return
     */
    private Path getPathDefault(){
        pathA.reset();
        pathA.lineTo(0, viewHeight);
        pathA.lineTo(viewWidth,viewHeight);
        pathA.lineTo(viewWidth,0);
        pathA.close();
        return pathA;
    }

    /**
     * 获取f点在右上角的pathA
     * @return
     */
    private Path getPathAFromTopRight(){
        pathA.reset();
        pathA.lineTo(c.x,c.y);//移动到c点
        pathA.quadTo(e.x,e.y,b.x,b.y);//从c到b画贝塞尔曲线，控制点为e
        pathA.lineTo(a.x,a.y);//移动到a点
        pathA.lineTo(k.x,k.y);//移动到k点
        pathA.quadTo(h.x,h.y,j.x,j.y);//从k到j画贝塞尔曲线，控制点为h
        pathA.lineTo(viewWidth,viewHeight);//移动到右下角
        pathA.lineTo(0, viewHeight);//移动到左下角
        pathA.close();
        return pathA;
    }

    /**
     * 获取f点在右下角的pathA
     * @return
     */
    private Path getPathAFromLowerRight(){
        pathA.reset();
        pathA.lineTo(0, viewHeight);//移动到左下角
        pathA.lineTo(c.x,c.y);//移动到c点
        pathA.quadTo(e.x,e.y,b.x,b.y);//从c到b画贝塞尔曲线，控制点为e
        pathA.lineTo(a.x,a.y);//移动到a点
        pathA.lineTo(k.x,k.y);//移动到k点
        pathA.quadTo(h.x,h.y,j.x,j.y);//从k到j画贝塞尔曲线，控制点为h
        pathA.lineTo(viewWidth,0);//移动到右上角
        pathA.close();//闭合区域
        return pathA;
    }

    /**
     * 绘制B区域内容
     * @param canvas
     * @param pathA
     */
    private void drawPathBContent(Canvas canvas, Path pathA){
        canvas.save();
        canvas.clipPath(pathA, Canvas.ClipOp.INTERSECT);//裁剪出A区域

        canvas.clipPath(getPathC(), Canvas.ClipOp.DIFFERENCE);//裁剪出B区域中不同于与AC区域的部分
        PixelMapHolder pixelMapHolder = new PixelMapHolder(pathBContentBitmap);
        canvas.drawPixelMapHolder(pixelMapHolder, 0, 0, pathCContentPaint);

//        drawPathBShadow(canvas);
        canvas.restore();
    }

    /**
     * 绘制B区域阴影，阴影左深右浅
     * @param canvas
     */
    private void drawPathBShadow(Canvas canvas){
        int deepOffset = 0;//深色端的偏移值
        int lightOffset = 0;//浅色端的偏移值
        float aTof =(float) Math.hypot((a.x - f.x),(a.y - f.y));//a到f的距离
        float viewDiagonalLength = (float) Math.hypot(viewWidth, viewHeight);//对角线长度

        int left;
        int right;
        int top = (int) c.y;
        int bottom = (int) (viewDiagonalLength + c.y);
        ShapeElement gradientDrawable;
        if(style.equals(STYLE_TOP_RIGHT)){//f点在右上角
            //从左向右线性渐变
            gradientDrawable = drawableBTopRight;

            left = (int) (c.x - deepOffset);//c点位于左上角
            right = (int) (c.x + aTof/4 + lightOffset);
        }else {
            //从右向左线性渐变
            gradientDrawable = drawableBLowerRight;

            left = (int) (c.x - aTof/4 - lightOffset);//c点位于左下角
            right = (int) (c.x + deepOffset);
        }
        gradientDrawable.setBounds(left,top,right,bottom);//设置阴影矩形

        float rotateDegrees = (float) Math.toDegrees(Math.atan2(e.x- f.x, h.y - f.y));//旋转角度
        canvas.rotate(rotateDegrees, c.x, c.y);//以c为中心点旋转
        gradientDrawable.drawToCanvas(canvas);
    }

    /**
     * 绘制区域B
     * @return
     */
    private Path getPathB(){
        pathB.reset();
        pathB.lineTo(0, viewHeight);//移动到左下角
        pathB.lineTo(viewWidth,viewHeight);//移动到右下角
        pathB.lineTo(viewWidth,0);//移动到右上角
        pathB.close();//闭合区域
        return pathB;
    }

    /**
     * 绘制C区域内容
     * @param canvas
     * @param pathA
     */
    private void drawPathCContent(Canvas canvas, Path pathA){
        canvas.save();
        canvas.clipPath(pathA, Canvas.ClipOp.INTERSECT);
        canvas.clipPath(getPathC(), Canvas.ClipOp.DIFFERENCE);//裁剪出C区域不同于A区域的部分
//        canvas.drawPath(getPathC(),pathCPaint);

        float eh = (float) Math.hypot(f.x - e.x,h.y - f.y);
        float sin0 = (f.x - e.x) / eh;
        float cos0 = (h.y - f.y) / eh;
        //设置翻转和旋转矩阵
        mMatrixArray[0] = -(1-2 * sin0 * sin0);
        mMatrixArray[1] = 2 * sin0 * cos0;
        mMatrixArray[3] = 2 * sin0 * cos0;
        mMatrixArray[4] = 1 - 2 * sin0 * sin0;

        mMatrix.reset();
        mMatrix.setElements(mMatrixArray);//翻转和旋转
        mMatrix.preTranslate(-e.x, -e.y);//沿当前XY轴负方向位移得到 矩形A₃B₃C₃D₃
        mMatrix.postTranslate(e.x, e.y);//沿原XY轴方向位移得到 矩形A4 B4 C4 D4
        PixelMapHolder pixelMapHolder = new PixelMapHolder(pathAContentBitmap);
        canvas.setMatrix(mMatrix);
        canvas.drawPixelMapHolder(pixelMapHolder,0,0,pathCContentPaint);

//        drawPathCShadow(canvas);
        canvas.restore();
    }

    /**
     * 绘制C区域阴影，阴影左浅右深
     * @param canvas
     */
    private void drawPathCShadow(Canvas canvas){
        int deepOffset = 1;//深色端的偏移值
        int lightOffset = -30;//浅色端的偏移值
        float viewDiagonalLength = (float) Math.hypot(viewWidth, viewHeight);//view对角线长度
        int midpoint_ce = (int) (c.x + e.x) / 2;//ce中点
        int midpoint_jh = (int) (j.y + h.y) / 2;//jh中点
        float minDisToControlPoint = Math.min(Math.abs(midpoint_ce - e.x), Math.abs(midpoint_jh - h.y));//中点到控制点的最小值

        int left;
        int right;
        int top = (int) c.y;
        int bottom = (int) (viewDiagonalLength + c.y);
        ShapeElement gradientDrawable;
        if (style.equals(STYLE_TOP_RIGHT)) {
            gradientDrawable = drawableCTopRight;
            left = (int) (c.x - lightOffset);
            right = (int) (c.x + minDisToControlPoint + deepOffset);
        } else {
            gradientDrawable = drawableCLowerRight;
            left = (int) (c.x - minDisToControlPoint - deepOffset);
            right = (int) (c.x + lightOffset);
        }
        gradientDrawable.setBounds(left,top,right,bottom);

        float mDegrees = (float) Math.toDegrees(Math.atan2(e.x- f.x, h.y - f.y));
        canvas.rotate(mDegrees, c.x, c.y);
        gradientDrawable.drawToCanvas(canvas);
    }

    /**
     * 绘制区域C
     * @return
     */
    private Path getPathC(){
        pathC.reset();
        pathC.moveTo(i.x,i.y);//移动到i点
        pathC.lineTo(d.x,d.y);//移动到d点
        pathC.lineTo(b.x,b.y);//移动到b点
        pathC.lineTo(a.x,a.y);//移动到a点
        pathC.lineTo(k.x,k.y);//移动到k点
        pathC.close();//闭合区域
        return pathC;
    }

    /**
     * 计算各点坐标
     * @param a
     * @param f
     */
    private void calcPointsXY(MyPoint a, MyPoint f){
        g.x = (a.x + f.x) / 2;
        g.y = (a.y + f.y) / 2;

        e.x = g.x - (f.y - g.y) * (f.y - g.y) / (f.x - g.x);
        e.y = f.y;

        h.x = f.x;
        h.y = g.y - (f.x - g.x) * (f.x - g.x) / (f.y - g.y);

        c.x = e.x - (f.x - e.x) / 2;
        c.y = f.y;

        j.x = f.x;
        j.y = h.y - (f.y - h.y) / 2;

        b = getIntersectionPoint(a,e,c,j);
        k = getIntersectionPoint(a,h,c,j);

        d.x = (c.x + 2 * e.x + b.x) / 4;
        d.y = (2 * e.y + c.y + b.y) / 4;

        i.x = (j.x + 2 * h.x + k.x) / 4;
        i.y = (2 * h.y + j.y + k.y) / 4;

        //计算d点到ae的距离
        float lA = a.y-e.y;
        float lB = e.x-a.x;
        float lC = a.x*e.y-e.x*a.y;
        lPathAShadowDis = Math.abs((lA*d.x+lB*d.y+lC)/(float) Math.hypot(lA,lB));

        //计算i点到ah的距离
        float rA = a.y-h.y;
        float rB = h.x-a.x;
        float rC = a.x*h.y-h.x*a.y;
        rPathAShadowDis = Math.abs((rA*i.x+rB*i.y+rC)/(float) Math.hypot(rA,rB));
    }

    /**
     * 计算两线段相交点坐标
     * @param lineOne_My_pointOne
     * @param lineOne_My_pointTwo
     * @param lineTwo_My_pointOne
     * @param lineTwo_My_pointTwo
     * @return 返回该点
     */
    private MyPoint getIntersectionPoint(MyPoint lineOne_My_pointOne, MyPoint lineOne_My_pointTwo, MyPoint lineTwo_My_pointOne, MyPoint lineTwo_My_pointTwo){
        float x1,y1,x2,y2,x3,y3,x4,y4;
        x1 = lineOne_My_pointOne.x;
        y1 = lineOne_My_pointOne.y;
        x2 = lineOne_My_pointTwo.x;
        y2 = lineOne_My_pointTwo.y;
        x3 = lineTwo_My_pointOne.x;
        y3 = lineTwo_My_pointOne.y;
        x4 = lineTwo_My_pointTwo.x;
        y4 = lineTwo_My_pointTwo.y;

        float pointX =((x1 - x2) * (x3 * y4 - x4 * y3) - (x3 - x4) * (x1 * y2 - x2 * y1))
                / ((x3 - x4) * (y1 - y2) - (x1 - x2) * (y3 - y4));
        float pointY =((y1 - y2) * (x3 * y4 - x4 * y3) - (x1 * y2 - x2 * y1) * (y3 - y4))
                / ((y1 - y2) * (x3 - x4) - (x1 - x2) * (y3 - y4));

        return  new MyPoint(pointX,pointY);
    }

    /**
     * 计算C点的X值
     * @param a
     * @param f
     * @return
     */
    private float calcPointCX(MyPoint a, MyPoint f){
        MyPoint g,e;
        g = new MyPoint();
        e = new MyPoint();
        g.x = (a.x + f.x) / 2;
        g.y = (a.y + f.y) / 2;

        e.x = g.x - (f.y - g.y) * (f.y - g.y) / (f.x - g.x);
        e.y = f.y;

        return e.x - (f.x - e.x) / 2;
    }

    public float getViewWidth(){
        return viewWidth;
    }

    public float getViewHeight(){
        return viewHeight;
    }



}
